package com.lions.client.model;

import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.user.client.ui.Image;

/**
 * The data representing the module.
 * @author Brad
 *
 */
public class Module {

	/**
	 * Random Module constructor. Constructs Module with given Type and Random X and Y values.
	 */
	public Module(Type t) {
		this.type = t;
		this.condition = Condition.USABLE;
		this.turns = 0;
		this.code = (int)(Math.random()*100);
		x = (int)(Math.random()*100);
		y = (int)(Math.random()*50);

	}

	/**
	 * Not a deep copy constructor, but a copy
	 * constructor nonetheless.
	 * 
	 * @param m
	 */
	public Module(Module m) {
		this.type = m.getType();
		this.condition = m.getCondition();
		this.turns = m.getTurns();
		this.code = m.getCode();
		x = m.getX();
		y = m.getY();
	}

	/**
	 * This is a deep copy constructor.
	 * @param type
	 * @param condition
	 * @param code
	 * @param turns
	 * @param xCoord
	 * @param yCoord
	 * @param collected
	 */
	public Module(Type type, Condition condition, int code, int turns,
			int xCoord, int yCoord, boolean collected) {
		this.type = type;
		this.condition = condition;
		this.turns = turns;
		this.code = code;
		x = xCoord;
		y = yCoord;
		collected = false;
	}
	
	/**
	 * Creates a module from a string in the format of
	 * AIRLOCK|USABLE|0|5|5|5|false
	 * @param s the String representing the new module
	 */
	public Module(String s) {
		
		// Set type
		int ZERO = 0;
		int index = s.indexOf("|");
		if( s.substring(ZERO, index).equals(Type.AIRLOCK.toString())) {
			this.type = Type.AIRLOCK;
		} else if( s.substring(ZERO, index).equals(Type.CANTEEN.toString())) {
			this.type = Type.CANTEEN;
		} else if( s.substring(ZERO, index).equals(Type.CONTROL.toString())) {
			this.type = Type.CONTROL;
		} else if( s.substring(ZERO, index).equals(Type.DORMITORY.toString())) {
			this.type = Type.DORMITORY;
		} else if( s.substring(ZERO, index).equals(Type.FOOD_WATER_STORAGE.toString())) {
			this.type = Type.FOOD_WATER_STORAGE;
		} else if( s.substring(ZERO, index).equals(Type.GYM.toString())) {
			this.type = Type.GYM;
		} else if( s.substring(ZERO, index).equals(Type.MEDICAL.toString())) {
			this.type = Type.MEDICAL;
		} else if( s.substring(ZERO, index).equals(Type.PLAIN.toString())) {
			this.type = Type.PLAIN;
		} else if( s.substring(ZERO, index).equals(Type.POWER.toString())) {
			this.type = Type.POWER;
		} else if( s.substring(ZERO, index).equals(Type.SANITATION.toString())) {
			this.type = Type.SANITATION;
		}
		
		// Set status
		s = s.substring(s.indexOf("|")+1);
		index = s.indexOf("|");
		if ( s.substring(ZERO, index).equals(Condition.REPAIRABLE.toString()) ) {
			this.condition = Condition.REPAIRABLE;
		} else if ( s.substring(ZERO, index).equals(Condition.UNREPAIRABLE.toString()) ) {
			this.condition = Condition.UNREPAIRABLE;
		} else if ( s.substring(ZERO, index).equals(Condition.USABLE.toString()) ) {
			this.condition = Condition.USABLE;
		}
		
		// Set turns
		s = s.substring(s.indexOf("|")+1);
		index = s.indexOf("|");
		this.turns = Integer.parseInt(s.substring(ZERO, index));
		
		// Set code
		s = s.substring(s.indexOf("|")+1);
		index = s.indexOf("|");
		this.code = Integer.parseInt(s.substring(ZERO, index));
		
		// Set X
		s = s.substring(s.indexOf("|")+1);
		index = s.indexOf("|");
		this.x = Integer.parseInt(s.substring(ZERO, index));
		
		// Set Y
		s = s.substring(s.indexOf("|")+1);
		index = s.indexOf("|");
		this.y = Integer.parseInt(s.substring(ZERO, index));
		
		// Set collected
		s = s.substring(s.indexOf("|")+1);
		if ( s.equals("false") ) {
			this.collected = false;
		} else if ( s.equals("true") ) {
			this.collected = true;
		}
	}

	/**
	 * Getter for the type of the specific module
	 * @return ENUM Type
	 */
	public Type getType() {
		return type;
	}
	
	public int getTypeAsInt() {
		int num = -1;
		if (this.type == Type.AIRLOCK) {
			num = 0;
		} else if (this.type == Type.CANTEEN) {
			num = 1;
		} else if (this.type == Type.CONTROL) {
			num = 2;
		} else if (this.type == Type.DORMITORY) {
			num = 3;
		} else if (this.type == Type.FOOD_WATER_STORAGE) {
			num = 4;
		} else if (this.type == Type.GYM) {
			num = 5;
		} else if (this.type == Type.MEDICAL) {
			num = 6;
		} else if (this.type == Type.PLAIN) {
			num = 7;
		} else if (this.type == Type.POWER) {
			num = 8;
		} else if (this.type == Type.SANITATION) {
			num = 9;
		}
		return num;
	}

	/**
	 * Setter for the specific module
	 * @param type ENUM Type
	 */
	public void setType(Type type) {
		this.type = type;
	}

	/**
	 * Getter for the condition of the specific module.
	 * @return condition ENUM Condition
	 */
	public Condition getCondition() {
		return condition;
	}
	
	public int getConditionAsInt() {
		int num = -1;
		if (this.condition == Condition.USABLE) {
			num = 0;
		} else if (this.condition == Condition.REPAIRABLE) {
			num = 1;
		} else if (this.condition == Condition.UNREPAIRABLE) {
			num = 2;
		}
		return num;
	}

	/**
	 * Setter for the condition of this specific module
	 * @param condition ENUM Condition
	 */
	public void setCondition(Condition condition) {
		this.condition = condition;
	}

	/**
	 * Gets the number of turns for this module to be upright
	 * @return integer turns
	 */
	public int getTurns() {
		return turns;
	}

	/**
	 * Setter for the number of turns to make this module upright
	 * @param integer turns 
	 */
	public void setTurns(int turns) {
		this.turns = turns;
	}

	/**
	 * The module type code for this specific module
	 * @return integer code
	 */
	public int getCode() {
		return code;
	}

	/**
	 * Setter for the module code number
	 * @param integer code 
	 */
	public void setCode(int code) {
		this.code = code;
	}

	/**
	 * Getter for the x-coordinate of the module.
	 * @return integer X
	 */
	public int getX() {
		return x;
	}

	/**
	 * Setter for the x-coordinate of the module
	 * @param integer x
	 */
	public void setX(int x) {
		this.x = x;
	}

	/**
	 * Getter for the y-coordinate of the module
	 * @return integer Y
	 */
	public int getY() {
		return y;
	}

	/**
	 * Setter for the y-coordinate of the module
	 * @param y integer y
	 */
	public void setY(int y) {
		this.y = y;
	}

	/**
	 * This is a boolean representation of the modules collected status
	 * True if the module is collected, or else false
	 * @return boolean collected
	 */
	public boolean isCollected() {
		return collected;
	}

	/**
	 * Setter for the 
	 * @param b
	 */
	public void setCollected(boolean b) {
		this.collected = b;
	}

	/**
	 * Retuns the particular image that represents this module
	 * @return ImageElement .jpg
	 */
	public ImageElement getImage() {
		Image img;
		ImageElement module;

		switch (type) {
		case AIRLOCK:
			img = new Image("images/Airlock.jpg");
			module = ImageElement.as(img.getElement());
		case CONTROL:
			img = new Image("images/Control.jpg");
			module = ImageElement.as(img.getElement());
		case POWER:
			img = new Image("images/Power.jpg");
			module = ImageElement.as(img.getElement());
			System.out.println("power");
		case FOOD_WATER_STORAGE:
			img = new Image("images/Food.jpg");
			module = ImageElement.as(img.getElement());
		case DORMITORY:
			img = new Image("images/Dormitory.jpg");
			module = ImageElement.as(img.getElement());
		case CANTEEN:
			img = new Image("images/Canteen.jpg");
			module = ImageElement.as(img.getElement());
		case SANITATION:
			img = new Image("images/Sanitation.jpg");
			module = ImageElement.as(img.getElement());
		case GYM:
			img = new Image("images/Airlock.jpg");
			module = ImageElement.as(img.getElement());
		case MEDICAL:
			img = new Image("images/Medical.jpg");
			module = ImageElement.as(img.getElement());
		case PLAIN:
			img = new Image("images/Plain.jpg");
			module = ImageElement.as(img.getElement());
		default:
			img = new Image("images/MarsImage.jpg");
			module = ImageElement.as(img.getElement());

		}
		return module;
	}
	
	/**
	 * The to string for this module.
	 * This is used for saving to HTML5
	 * session storage
	 * AIRLOCK|USABLE|0|5|5|5|false
	 */
	@Override
	public String toString() {
		String modString = "";
		modString = type.toString()+"|"
				+ condition.toString()+"|"
				+ turns+"|"
				+ code+"|"
				+ x+"|"
				+ y+"|"
				+ collected;

		return modString;
	}

	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 * This equals does not contain the field "collected"
	 * Use this to see if a module is a duplicate to one marked collected.
	 * @return true if other is a duplicate module.
	 */
	@Override
	public boolean equals(Object other){
		Module module = (Module)other;
		return(this.type == module.getType() &&
				this.condition == module.getCondition() &&
				this.turns == module.getTurns() &&
				this.code == module.getCode() &&
				this.x == module.getX() &&
				this.y == module.y);
	}
	private Type type;
	private Condition condition;
	private int turns;
	private int code;
	private int x;
	private int y;
	private boolean collected;
}
